<template>
  <q-select
    filled
    use-input
    hide-selected
    fill-input
    hide-dropdown-icon
    input-debounce="500"
    v-model="field.value"
    :options="options"
    :label="field.label"
    lazy-rules
    :rules="field.rules ? field.rules : null"
    @filter="filterFn"
    @input-value="setModel"
    @popup-show="selectPop"
    :readonly="readonly"
    :dense="dense"
    ref="select"
    bottom-slots
    v-bind="$attrs"
  >
    <template v-slot:hint v-if="field.hint || field.compare">
      <div class="text-bold text-white bg-yellow-10" style="padding: 1px;" v-if="canShowCompare">
        {{field.compare.label ? field.compare.label + '：' : ''}}{{field.compare.map ? field.compare.map.value : field.compare.value}}
      </div>
      <div v-if="field.hint">{{field.hint}}</div>
    </template>
  </q-select>
</template>

<script>
import { defineComponent } from 'vue';
import pinyin from 'src/lib/vue-py';
import { useStore } from 'stores/store';

export default defineComponent({
  name: 'autocomplete',
  props: {
    field: {
      type: Object,
      default: () => []
    }
  },
  emits: ['update:modelValue'],
  data () {
    const $store = useStore();
    if (!this.field.options) this.field.options = [];
    if (this.field.dict && $store.dictionary[this.field.dict] && this.field.options.length == 0) {
      this.field.options = JSON.parse(JSON.stringify($store.dictionary[this.field.dict].map(v => v.label)));
    }

    return {
      options: this.field.options,
      $store
    }
  },
  methods: {
    filterFn (val, update, abort) {
      const $store = useStore();
      if (typeof this.field.filterFn === 'function') {
        this.field.filterFn(val, abort, opts => {
          update(() => {
            this.options = opts;
          });
        });
      } else {
        if (!this.field.options) this.field.options = [];
        if (this.field.dict && $store.dictionary[this.field.dict] && this.field.options.length == 0) {
          this.field.options = JSON.parse(JSON.stringify($store.dictionary[this.field.dict].map(v => v.label)));
        }

        update(() => {
          const query = this.field.value || '';
          this.options = this.field.options.filter(v => {
            const py = pinyin.chineseToPinYin(v || '', true).toLowerCase() || '';
            return v && (v.indexOf(query) > -1 || py.indexOf(query.toLowerCase()) > -1)
          });
        })
      }
    },
    setModel (val) {
      this.field.value = val;
    },
    selectPop () {
      // 点击时第二次触发查询
      if (!!this.field.value && this.options.length === 0) {
        this.$refs.select.updateInputValue(this.field.value);
      }
    }
  },
  computed: {
    readonly () {
      return !!this.field.readonly;
    },
    dense () {
      return !!this.field.dense;
    },
    canShowCompare () {
      return this.field.compare && this.field.compare.value !== null && (this.field.compare.always || this.field.compare.value != this.field.value);
    }
  },
  watch: {
    '$store.dictionary' (val) { // 字典有数据后，加载到options
      if (this.field.dict && val[this.field.dict] && this.options.length < 1) {
        this.field.options = JSON.parse(JSON.stringify(this.$store.dictionary[this.field.dict].map(v => v.label)));
        this.options = this.field.options;
      }
    },
    'field.dict' (val) {
      if (this.field.dict && this.$store.dictionary[this.field.dict]) {
        this.field.options = this.options = JSON.parse(JSON.stringify(this.$store.dictionary[this.field.dict].map(v => v.label)));
      } else {
        this.field.options = this.options = [];
      }
    },
    'field.value' (val) {
      this.$emit('update:modelValue', val);
    }
  }
})
</script>
